#define   NONAMELESSUNION
#include <windows.h>
#include <vector.h>

HINSTANCE g_hInstance;

vector<HWND> g_hwnds; // (STDCALL_RUN, STDCALL_GETHWNDS)

BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID) 
{
	if (fdwReason == DLL_PROCESS_ATTACH) {
		g_hInstance = hInstance;
	}
	return TRUE;
}


BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM)
{
	g_hwnds.push_back(hwnd);
	return TRUE;
}

STDAPI __export STDCALL_RUN(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
	g_hwnds.clear();
	pRes->n1.n2.vt = VT_BOOL;
	pRes->n1.n2.n3.boolVal = EnumWindows(EnumWindowsProc, NULL);
	return S_OK;
}

STDAPI __export STDCALL_GETHWNDS(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
	long size = g_hwnds.size();
	SAFEARRAY *pArray = SafeArrayCreateVector(VT_VARIANT, 0, size);
	for(long i=0; i<size; i++) {
		VARIANT var;
		VariantInit(&var);
		var.n1.n2.vt = VT_I4;
		var.n1.n2.n3.lVal = (LONG)(g_hwnds[i]);
		SafeArrayPutElement(pArray, &i, &var);
	}
	pRes->n1.n2.vt = VT_ARRAY|VT_VARIANT;
	pRes->n1.n2.n3.parray = pArray;
	return S_OK;
}

STDAPI __export STDCALL_GETHWNDBYTITLESTARTSWITH(WORD, DISPPARAMS FAR* pDispParams, VARIANT FAR* pRes, EXCEPINFO FAR*) {

	if (pDispParams->cArgs < 1) return DISP_E_BADPARAMCOUNT;	

	LPCWSTR lpWindowTitle = NULL;	
	if ((pDispParams->rgvarg[0].n1.n2.vt & VT_BSTR) > 0) {
		lpWindowTitle = pDispParams->rgvarg[0].n1.n2.n3.bstrVal;
	};
	
	if (lpWindowTitle == NULL) return DISP_E_BADVARTYPE; 
	
	pRes->n1.n2.vt = VT_I4;
	pRes->n1.n2.n3.lVal = 0;
	
	long size = g_hwnds.size();	
	for(long i=0; i<size; i++) {
		HWND hwnd = g_hwnds[i];
		int length = GetWindowTextLength(hwnd);
		if (length == 0) continue;

		PWSTR buf = (PWSTR)calloc(length + 1, sizeof(wchar_t));
		if (buf == NULL) break;
		GetWindowTextW(hwnd, buf, length);
		
		wchar_t* p = wcsstr(buf, lpWindowTitle);
		if (p == buf) {
			pRes->n1.n2.vt = VT_I4;
			pRes->n1.n2.n3.lVal = (LONG)hwnd;
		};
		
		free(buf);
		if (pRes->n1.n2.n3.lVal != 0) break;
	}

	return S_OK;
}


STDAPI __export STDCALL_FINDWINDOW(WORD, DISPPARAMS FAR* pDispParams, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
	LPCWSTR lpClassName = NULL;
	LPCWSTR lpWindowName = NULL;
	
	if (pDispParams->cArgs < 2) return DISP_E_BADPARAMCOUNT;
	
	if (pDispParams->rgvarg[0].n1.n2.vt == VT_BSTR) 
		lpWindowName = pDispParams->rgvarg[0].n1.n2.n3.bstrVal;

	if (pDispParams->rgvarg[1].n1.n2.vt == VT_BSTR) 
		lpClassName = pDispParams->rgvarg[1].n1.n2.n3.bstrVal;
		
	pRes->n1.n2.vt = VT_I4;
	pRes->n1.n2.n3.lVal = (LONG)FindWindowW(lpClassName, lpWindowName);
	
	return S_OK;
}


STDAPI __export STDCALL_GETCLASSNAME(WORD, DISPPARAMS FAR* pDispParams, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{

	if (pDispParams->cArgs < 1) return DISP_E_BADPARAMCOUNT;
	
	VARIANT varHwnd;
	VariantInit(&varHwnd);
	VariantCopyInd(&varHwnd, &pDispParams->rgvarg[0]);
	HRESULT hr = VariantChangeType(&varHwnd, &varHwnd, 0, VT_I4);
	if FAILED(hr) return hr;
	HWND hWnd = (HWND)varHwnd.n1.n2.n3.lVal;
	
	PWSTR buf = (PWSTR)calloc(MAX_PATH, sizeof(wchar_t));

	if (buf == NULL) return E_OUTOFMEMORY;

	GetClassNameW(hWnd, buf, MAX_PATH);

	pRes->n1.n2.vt = VT_BSTR;
	pRes->n1.n2.n3.bstrVal = SysAllocString(buf);
	
	free(buf);
	
	return S_OK;
}


STDAPI __export STDCALL_GETCLIENTRECT(WORD, DISPPARAMS FAR* pDispParams, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
	if (pDispParams->cArgs < 1) return DISP_E_BADPARAMCOUNT;
	
	VARIANT varHwnd;
	VariantInit(&varHwnd);
	VariantCopyInd(&varHwnd, &pDispParams->rgvarg[0]);
	HRESULT hr = VariantChangeType(&varHwnd, &varHwnd, 0, VT_I4);
	if FAILED(hr) return hr;
	HWND hWnd = (HWND)varHwnd.n1.n2.n3.lVal;

	RECT rect = {0};
	GetClientRect(hWnd, &rect);

	long size = 4;
	SAFEARRAY *pArray = SafeArrayCreateVector(VT_VARIANT, 0, size);
	for(long i=0; i<size; i++) {
		VARIANT var;
		VariantInit(&var);
		var.n1.n2.vt = VT_I4;
		switch(i) {
			case 0: 
				var.n1.n2.n3.lVal = rect.left;
				break;
			case 1: 
				var.n1.n2.n3.lVal = rect.top;
				break;
			case 2: 
				var.n1.n2.n3.lVal = rect.right;
				break;
			case 3: 
				var.n1.n2.n3.lVal = rect.bottom;
				break;
		}

		SafeArrayPutElement(pArray, &i, &var);
	}
	pRes->n1.n2.vt = VT_ARRAY|VT_VARIANT;
	pRes->n1.n2.n3.parray = pArray;

	return S_OK;
}



#ifdef GW_CHILD
STDAPI __export CONST_GW_CHILD(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = GW_CHILD;
	return S_OK;
}
#endif

#ifdef GW_ENABLEDPOPUP
STDAPI __export CONST_GW_ENABLEDPOPUP(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = GW_ENABLEDPOPUP;
	return S_OK;
}
#endif

#ifdef GW_HWNDFIRST
STDAPI __export CONST_GW_HWNDFIRST(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = GW_HWNDFIRST;
	return S_OK;
}
#endif

#ifdef GW_HWNDLAST
STDAPI __export CONST_GW_HWNDLAST(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = GW_HWNDLAST;
	return S_OK;
}
#endif

#ifdef GW_HWNDNEXT
STDAPI __export CONST_GW_HWNDNEXT(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = GW_HWNDNEXT;
	return S_OK;
}
#endif

#ifdef GW_HWNDPREV
STDAPI __export CONST_GW_HWNDPREV(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = GW_HWNDPREV;
	return S_OK;
}
#endif

#ifdef GW_OWNER
STDAPI __export CONST_GW_OWNER(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = GW_OWNER;
	return S_OK;
}
#endif

STDAPI __export STDCALL_GETWINDOW(WORD, DISPPARAMS FAR* pDispParams, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
	if (pDispParams->cArgs < 2) return DISP_E_BADPARAMCOUNT;

	VARIANT varCmd;
	VariantInit(&varCmd);
	VariantCopyInd(&varCmd, &pDispParams->rgvarg[0]);
	HRESULT hr = VariantChangeType(&varCmd, &varCmd, 0, VT_I4);
	if FAILED(hr) return hr;
	UINT uCmd = varCmd.n1.n2.n3.lVal;
	
	VARIANT varHwnd;
	VariantInit(&varHwnd);
	VariantCopyInd(&varHwnd, &pDispParams->rgvarg[1]);
	hr = VariantChangeType(&varHwnd, &varHwnd, 0, VT_I4);
	if FAILED(hr) return hr;
	HWND hWnd = (HWND)varHwnd.n1.n2.n3.lVal;

	pRes->n1.n2.vt = VT_I4;
	pRes->n1.n2.n3.lVal = (LONG)GetWindow(hWnd, uCmd);
	
	return S_OK;
}



STDAPI __export STDCALL_GETWINDOWRECT(WORD, DISPPARAMS FAR* pDispParams, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
	if (pDispParams->cArgs < 1) return DISP_E_BADPARAMCOUNT;
	
	VARIANT varHwnd;
	VariantInit(&varHwnd);
	VariantCopyInd(&varHwnd, &pDispParams->rgvarg[0]);
	HRESULT hr = VariantChangeType(&varHwnd, &varHwnd, 0, VT_I4);
	if FAILED(hr) return hr;
	HWND hWnd = (HWND)varHwnd.n1.n2.n3.lVal;

	RECT rect = {0};
	GetWindowRect(hWnd, &rect);

	long size = 4;
	SAFEARRAY *pArray = SafeArrayCreateVector(VT_VARIANT, 0, size);
	for(long i=0; i<size; i++) {
		VARIANT var;
		VariantInit(&var);
		var.n1.n2.vt = VT_I4;
		switch(i) {
			case 0: 
				var.n1.n2.n3.lVal = rect.left;
				break;
			case 1: 
				var.n1.n2.n3.lVal = rect.top;
				break;
			case 2: 
				var.n1.n2.n3.lVal = rect.right;
				break;
			case 3: 
				var.n1.n2.n3.lVal = rect.bottom;
				break;
		}

		SafeArrayPutElement(pArray, &i, &var);
	}
	pRes->n1.n2.vt = VT_ARRAY|VT_VARIANT;
	pRes->n1.n2.n3.parray = pArray;

	return S_OK;
}



STDAPI __export STDCALL_GETWINDOWTEXT(WORD, DISPPARAMS FAR* pDispParams, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
	if (pDispParams->cArgs < 1) return DISP_E_BADPARAMCOUNT;
	
	VARIANT varHwnd;
	VariantInit(&varHwnd);
	VariantCopyInd(&varHwnd, &pDispParams->rgvarg[0]);
	HRESULT hr = VariantChangeType(&varHwnd, &varHwnd, 0, VT_I4);
	if FAILED(hr) return hr;
	HWND hWnd = (HWND)varHwnd.n1.n2.n3.lVal;

	int iLength = GetWindowTextLengthW(hWnd) + 1;
	
	PWSTR buf = (PWSTR)calloc(iLength + 1, sizeof(wchar_t));

	if (buf == NULL) return E_OUTOFMEMORY;

	GetWindowTextW(hWnd, buf, iLength);

	pRes->n1.n2.vt = VT_BSTR;
	pRes->n1.n2.n3.bstrVal = SysAllocString(buf);
	
	free(buf);
	
	return S_OK;
}



#ifdef MB_OK
STDAPI __export CONST_MB_OK(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_OK;
	return S_OK;
}
#endif

#ifdef MB_OKCANCEL
STDAPI __export CONST_MB_OKCANCEL(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_OKCANCEL;
	return S_OK;
}
#endif

#ifdef MB_ABORTRETRYIGNORE
STDAPI __export CONST_MB_ABORTRETRYIGNORE(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_ABORTRETRYIGNORE;
	return S_OK;
}
#endif

#ifdef MB_YESNOCANCEL
STDAPI __export CONST_MB_YESNOCANCEL(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_YESNOCANCEL;
	return S_OK;
}
#endif

#ifdef MB_YESNO
STDAPI __export CONST_MB_YESNO(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_YESNO;
	return S_OK;
}
#endif

#ifdef MB_RETRYCANCEL
STDAPI __export CONST_MB_RETRYCANCEL(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_RETRYCANCEL;
	return S_OK;
}
#endif

#ifdef MB_CANCELTRYCONTINUE
STDAPI __export CONST_MB_CANCELTRYCONTINUE(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_CANCELTRYCONTINUE;
	return S_OK;
}
#endif

#ifdef MB_ICONHAND
STDAPI __export CONST_MB_ICONHAND(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_ICONHAND;
	return S_OK;
}
#endif

#ifdef MB_ICONQUESTION
STDAPI __export CONST_MB_ICONQUESTION(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_ICONQUESTION;
	return S_OK;
}
#endif

#ifdef MB_ICONEXCLAMATION
STDAPI __export CONST_MB_ICONEXCLAMATION(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_ICONEXCLAMATION;
	return S_OK;
}
#endif

#ifdef MB_ICONASTERISK
STDAPI __export CONST_MB_ICONASTERISK(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_ICONASTERISK;
	return S_OK;
}
#endif

#ifdef MB_DEFBUTTON1
STDAPI __export CONST_MB_DEFBUTTON1(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_DEFBUTTON1;
	return S_OK;
}
#endif

#ifdef MB_DEFBUTTON2
STDAPI __export CONST_MB_DEFBUTTON2(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_DEFBUTTON2;
	return S_OK;
}
#endif

#ifdef MB_DEFBUTTON3
STDAPI __export CONST_MB_DEFBUTTON3(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_DEFBUTTON3;
	return S_OK;
}
#endif

#ifdef MB_DEFBUTTON4
STDAPI __export CONST_MB_DEFBUTTON4(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_DEFBUTTON4;
	return S_OK;
}
#endif

#ifdef MB_APPLMODAL
STDAPI __export CONST_MB_APPLMODAL(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_APPLMODAL;
	return S_OK;
}
#endif

#ifdef MB_SYSTEMMODAL
STDAPI __export CONST_MB_SYSTEMMODAL(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_SYSTEMMODAL;
	return S_OK;
}
#endif

#ifdef MB_TASKMODAL
STDAPI __export CONST_MB_TASKMODAL(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_TASKMODAL;
	return S_OK;
}
#endif

#ifdef MB_HELP
STDAPI __export CONST_MB_HELP(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_HELP;
	return S_OK;
}
#endif

#ifdef MB_NOFOCUS
STDAPI __export CONST_MB_NOFOCUS(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_NOFOCUS;
	return S_OK;
}
#endif

#ifdef MB_SETFOREGROUND
STDAPI __export CONST_MB_SETFOREGROUND(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_SETFOREGROUND;
	return S_OK;
}
#endif

#ifdef MB_DEFAULT_DESKTOP_ONLY
STDAPI __export CONST_MB_DEFAULT_DESKTOP_ONLY(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_DEFAULT_DESKTOP_ONLY;
	return S_OK;
}
#endif

#ifdef MB_TOPMOST
STDAPI __export CONST_MB_TOPMOST(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_TOPMOST;
	return S_OK;
}
#endif

#ifdef MB_RIGHT
STDAPI __export CONST_MB_RIGHT(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_RIGHT;
	return S_OK;
}
#endif

#ifdef MB_RTLREADING
STDAPI __export CONST_MB_RTLREADING(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = MB_RTLREADING;
	return S_OK;
}
#endif


/*
 * Dialog Box Command IDs
 */
 
#ifdef IDOK
STDAPI __export CONST_IDOK(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = IDOK;
	return S_OK;
}
#endif

#ifdef IDCANCEL
STDAPI __export CONST_IDCANCEL(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = IDCANCEL;
	return S_OK;
}
#endif
 
#ifdef IDABORT
STDAPI __export CONST_IDABORT(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = IDABORT;
	return S_OK;
}
#endif

#ifdef IDRETRY
STDAPI __export CONST_IDRETRY(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = IDRETRY;
	return S_OK;
}
#endif

#ifdef IDIGNORE
STDAPI __export CONST_IDIGNORE(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = IDIGNORE;
	return S_OK;
}
#endif

#ifdef IDYES
STDAPI __export CONST_IDYES(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = IDYES;
	return S_OK;
}
#endif

#ifdef IDNO
STDAPI __export CONST_IDNO(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = IDNO;
	return S_OK;
}
#endif

#ifdef IDCLOSE
STDAPI __export CONST_IDCLOSE(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = IDCLOSE;
	return S_OK;
}
#endif

#ifdef IDHELP
STDAPI __export CONST_IDHELP(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = IDHELP;
	return S_OK;
}
#endif

#ifdef IDTRYAGAIN
STDAPI __export CONST_IDTRYAGAIN(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = IDTRYAGAIN;
	return S_OK;
}
#endif

#ifdef IDCONTINUE
STDAPI __export CONST_IDCONTINUE(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
        pRes->n1.n2.vt = VT_I4;
        pRes->n1.n2.n3.lVal = IDCONTINUE;
	return S_OK;
}
#endif

STDAPI __export STDCALL_MSGBOX(WORD, DISPPARAMS FAR* pDispParams, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
	if (pDispParams->cArgs < 4) return DISP_E_BADPARAMCOUNT;
	
	VARIANT varType;
	VariantInit(&varType);
	VariantCopyInd(&varType, &pDispParams->rgvarg[0]);
	HRESULT hr = VariantChangeType(&varType, &varType, 0, VT_I4);
	if FAILED(hr) return hr;
	UINT uType = varType.n1.n2.n3.lVal;
	
	if (pDispParams->rgvarg[1].n1.n2.vt != VT_BSTR) return DISP_E_BADVARTYPE;
	BSTR title = pDispParams->rgvarg[1].n1.n2.n3.bstrVal;

	if (pDispParams->rgvarg[2].n1.n2.vt != VT_BSTR) return DISP_E_BADVARTYPE;	
	BSTR msg = pDispParams->rgvarg[2].n1.n2.n3.bstrVal;
	
	VARIANT varHwnd;
	VariantInit(&varHwnd);
	VariantCopyInd(&varHwnd, &pDispParams->rgvarg[3]);
	hr = VariantChangeType(&varHwnd, &varHwnd, 0, VT_I4);
	if FAILED(hr) return hr;
	HWND hWnd = (HWND)varHwnd.n1.n2.n3.lVal;

	pRes->n1.n2.vt = VT_I4;
	pRes->n1.n2.n3.lVal = MessageBoxW(hWnd, msg, title, uType);

	return S_OK;
}

STDAPI __export STDCALL_SETACTIVEWINDOW(WORD, DISPPARAMS FAR* pDispParams, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
	if (pDispParams->cArgs < 1) return DISP_E_BADPARAMCOUNT;
	
	VARIANT varHwnd;
	VariantInit(&varHwnd);
	VariantCopyInd(&varHwnd, &pDispParams->rgvarg[0]);
	HRESULT hr = VariantChangeType(&varHwnd, &varHwnd, 0, VT_I4);
	if FAILED(hr) return hr;
	HWND hWnd = (HWND)varHwnd.n1.n2.n3.lVal;
	
	pRes->n1.n2.vt = VT_I4;
	pRes->n1.n2.n3.lVal = (LONG)SetActiveWindow(hWnd);
	
	return S_OK;
}

